package accel.storage;

import accel.dataholders.Character;
import accel.dataholders.Stats;
import accel.dataholders.Weapon;
import accel.movement.AttackSet;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

public class DBManager extends SQLiteOpenHelper {

	private static final String dbName = "acceldb";
	private static final int version = 1;
	private Context con;
	
	private static DBManager instance = null;
	
	private DBManager(Context con)
	{
		super(con,dbName,null,version);
		this.con = con;
	}
	
	public static synchronized DBManager getInstance(Context con)
	{
		if (instance == null)
			instance = new DBManager(con);
		return instance;
	}
	
	@Override
	public void onCreate(SQLiteDatabase db) {
		try
		{
			db.execSQL("create table characters (_id integer primary key autoincrement, sname integer not null, portrait integer not null, level integer not null, exp integer not null, sDescId integer not null, sstr integer not null, sener integer not null, sheal integer not null, scha integer not null, sspeed integer not null, slearn integer not null," +
					"wstr integer not null, wener integer not null, wheal integer not null, wcha integer not null, wspeed integer not null, wlearn integer not null,wname integer not null, wportrait integer not null, wDescId integer not null, attackSet integer not null)");
		}
		catch(Exception e)
		{
			Toast.makeText(con, "Failed to deploy database", Toast.LENGTH_SHORT).show();
		}
		
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub
		
	}
	
	public Character [] loadCharacters()
	{
		Cursor cur = this.getReadableDatabase().rawQuery("select sname, portrait, sDescId, level, exp, sstr, sener, sheal, scha, sspeed, slearn," +
				"wname, wstr, wener, wheal, wcha, wspeed, wlearn, wportrait, wdescid, _id, attackSet from characters", new String[]{});
		Character cs [] = new Character [cur.getCount()];
		if (cur.getCount() == 0)
			return cs;
		Character s;
		Weapon w;
		int i = 0;
		cur.moveToFirst();
		do
		{
			s = new Character (cur.getInt(0), cur.getInt(1), cur.getInt(2), cur.getInt(3), cur.getInt(4), new Stats(cur.getInt(5), cur.getInt(6), cur.getInt(7), cur.getInt(8), cur.getInt(9), cur.getInt(10)),cur.getInt(20));
			w = new Weapon(cur.getInt(11), new Stats(cur.getInt(12), cur.getInt(13), cur.getInt(14), cur.getInt(15), cur.getInt(16), cur.getInt(17)), cur.getInt(18), cur.getInt(19));
			s.setWeapon(w);
			int ii = cur.getInt(21);
			s.setAttacks(AttackSet.attackCollection[cur.getInt(21)].generateForParent(s));
			cs [i++] = s;
		}
		while (cur.moveToNext());
		return cs;
	}
	
	public void saveNewCharacer(Character c)
	{
		Character s = c;
		Stats ss = s.getStats();
		Weapon w = c.getWeapon();
		Stats ws = w.getStats();
		try
		{
			this.getWritableDatabase().execSQL("insert into characters values(null, " + Integer.toString(s.getName()) + ","+Integer.toString(s.getPortrait())+", "+Integer.toString(s.getLevel())+", "+Integer.toString(s.getExp())+","+Integer.toString(s.getDesciption())+","+Integer.toString(ss.maxstrength)+"," +Integer.toString(ss.maxenergy)+","+Integer.toString(ss.maxhealth)+","+Integer.toString(ss.maxcharisma)+","+Integer.toString(ss.maxspeed)+","+Integer.toString(ss.maxlearningspeed)+","
					+ Integer.toString(ws.maxstrength)+"," +Integer.toString(ws.maxenergy)+","+Integer.toString(ws.maxhealth)+","+Integer.toString(ws.maxcharisma)+","+Integer.toString(ws.maxspeed)+","+Integer.toString(ws.maxlearningspeed) + ", "+Integer.toString(w.getName())+","+Integer.toString(w.getPortrait())+","+Integer.toString(w.getDesciption())+","+Integer.toString(AttackSet.getSetId(s.getAttacks()))+")");
			Cursor cur = this.getReadableDatabase().rawQuery("select _id from characters order by _id desc limit 0,1", new String[]{});
			cur.moveToFirst();
			c.setDBID(cur.getInt(0));
		}
		catch (Exception e)
		{
			Toast.makeText(con, "Failed to save character", Toast.LENGTH_SHORT).show();
		}
	}
	
	public class CharacterDBIDNotSpecified extends Exception
	{
		@Override
		public String getMessage()
		{
			return "Character passed to DBManager does not contain any specified identifier";
		}
		
		@Override
		public String toString()
		{
			return getMessage();
		}
	}
	
	public void updateCharacter(Character c) throws CharacterDBIDNotSpecified
	{
		if (c.DBID() == -1)
			throw new CharacterDBIDNotSpecified();
		Character s = c;
		Stats ss = s.getStats();
		this.getWritableDatabase().execSQL("update characters set level = "+s.getLevel()+", exp = "+s.getExp()+", sstr = "+ss.maxstrength+",sener = "+ss.maxenergy+", sheal = "+ss.maxhealth+", scha = "+ss.maxcharisma+", sspeed = "+ss.maxspeed+" where _id = " + c.DBID());
	}
	
	public void deleteCharacter(Character c) throws CharacterDBIDNotSpecified
	{
		if (c.DBID() == -1)
			throw new CharacterDBIDNotSpecified();
		this.getWritableDatabase().execSQL("delete from characters where _id = " + c.DBID());
	}
	
}
